#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h> // 包含close函数的声明

// 将MAC地址字符串转换为字节序列
void macStringToBytes(const char* macStr, uint8_t* macBytes) {
    sscanf(macStr, "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
           &macBytes[0], &macBytes[1], &macBytes[2],
           &macBytes[3], &macBytes[4], &macBytes[5]);
}

// 发送魔法包
bool sendMagicPacket(const char* macStr, const char* broadcastIP) {
    uint8_t macBytes[6];
    macStringToBytes(macStr, macBytes);

    // 创建魔法包
    uint8_t magicPacket[102];
    memset(magicPacket, 0xFF, 6); // 填充前6个字节为FF
    for (int i = 1; i <= 16; i++) {
        memcpy(magicPacket + i * 6, macBytes, 6); // 添加MAC地址
    }

    // 创建UDP套接字
    int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sock < 0) {
        std::cerr << "无法创建套接字" << std::endl;
        return false;
    }

    // 设置广播选项
    int broadcast = 1;
    if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) < 0) {
        std::cerr << "无法设置广播选项" << std::endl;
        close(sock);
        return false;
    }

    // 设置目标地址
    sockaddr_in targetAddr;
    memset(&targetAddr, 0, sizeof(targetAddr));
    targetAddr.sin_family = AF_INET;
    targetAddr.sin_addr.s_addr = inet_addr(broadcastIP);
    targetAddr.sin_port = htons(7); // WOL端口

    // 发送魔法包
    if (sendto(sock, magicPacket, sizeof(magicPacket), 0, (sockaddr*)&targetAddr, sizeof(targetAddr)) < 0) {
        std::cerr << "发送魔法包失败" << std::endl;
        close(sock);
        return false;
    }

    close(sock);
    return true;
}

int main(int argc, char* argv[]) {
    if (argc != 2) {
        std::cerr << "用法: " << argv[0] << " <MAC地址>" << std::endl;
        std::cerr << "示例: " << argv[0] << " 00:1A:2B:3C:4D:5E" << std::endl;
        return 1;
    }

    const char* macAddress = argv[1]; // 从命令行参数获取MAC地址
    const char* broadcastIP = "255.255.255.255"; // 广播地址

    if (sendMagicPacket(macAddress, broadcastIP)) {
        std::cout << "魔法包已发送" << std::endl;
    } else {
        std::cout << "发送魔法包失败" << std::endl;
    }

    return 0;
}